<template>
  <div class="add-depa">
    <el-dialog :title="mytitle" :visible="showDialog">
      <el-form
        ref="myform"
        :model="formData"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="formData.name"></el-input>
        </el-form-item>
        <el-form-item label="部门编号" prop="code">
          <el-input v-model="formData.code"></el-input>
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="formData.manager">
            <el-option
              v-for="item in people"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="formData.introduce"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button @click="submit" type="primary">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  getDepartmentApi,
  addDepartmentApi,
  getDepartmentByIdApi,
  updateDeparmentApi
} from '@/api/department'
// 操作操作员工的方法
import { getSimpleUserAPi } from '@/api/employees'
export default {
  // showDialog：用来控制面板的显示与隐藏
  // currentObj：用来记录当前要添加子部门的数据源
  props: ['showDialog', 'currentObj'],
  data () {
    return {
      formData: {
        name: '', // 部门名称
        code: '', // 部门编号
        manager: '', // 部门负责人
        introduce: '' // 部门介绍
      },
      // 配置校验规则
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '部门名称长度在 1~50 之间',
            trigger: 'blur'
          },
          // 添加自定义校验规则
          {
            validator: async (rules, value, callback) => {
              // 1.0 得到所有的总数数据
              const res = await getDepartmentApi()
              // 2.0 得到当前操作的部门下面的所有的子部门
              // 判断当前的操作：修改 & 新增
              if (!this.formData.id) {
                // 新增：
                // 判断这个数组中是否存在元素的 name 属性与当输入框中的内容相同
                var bool = res.depts
                  .filter(item => {
                    // 当前所有同级部门 & 不能包含自己
                    return item.pid === this.currentObj.id
                  })
                  .some(item => {
                    return item.name === value
                  })
              } else {
                // 修改：
                var bool = res.depts
                  .filter(item => {
                    return (
                      // 得到当前所有的同级元素 & 当前元素不能包含在其中
                      item.pid === this.currentObj.pid &&
                      item.id !== this.currentObj.id
                    )
                  })
                  .some(item => {
                    return item.name === value
                  })
              }
              !bool
                ? callback()
                : callback(new Error('当前部门下已有同名的部门'))
              // some 遍历数组，返回一个 bool 值，只要数组中有一个元素满足条件，返回 true，否则返回 false
              // // value：表单元素中要校验的值，
              // // callback 回调函数
              // //  校验通过： callback()
              // //  校验失败： callback(new Error(''))
              // // 需求：同级部门中禁止出现重复部门名
              // // 1.0 得到所有的部门数据（组织架构）
              // const res = await getDepartmentApi()
              // console.log(res.depts)
              // // 2.0 得到当前要添加子部门的元素  currentObj
              // // console.log(this.currentObj)
              // // 3.0 从数据源中得到所有的同级部门
              // var sameList = res.depts.filter(item => {
              //   return item.pid === this.currentObj.id
              // })
              // // 4.0 验证：当前添加的 value 在同级部门中是否已经存在了
              // // 定义一个 bool 值，用来表示当前结构中是否存在同步的 name 与 value 相同
              // var hasSameName = false
              // sameList.forEach(item => {
              //   if (item.name === value) {
              //     hasSameName = true
              //   }
              // })
              // // 5.0 执行后续代码 hasSameName :
              // //  1)true,说明在同级中有相同名称的部门，应该提示错误信息,
              // //  2)false，说明在同级中没有相同名称的部门，应该直接验证通过
              // if (hasSameName) {
              //   callback(new Error('当前部门下已有同名的部门'))
              // } else {
              //   callback()
              // }
            }
          }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '部门编码长度在 1~50 之间',
            trigger: 'blur'
          },
          {
            validator: async (rules, value, callback) => {
              // 需求：验证 value 是否在所有数据源中的 code 出现过，
              //    出现过 callback(new Error())
              //    款出现 callback()
              // 1.0 得到所有的数据源
              const res = await getDepartmentApi()
              // 2.0 遍历所有的数据源，从中打出 code 是否与 value 相同
              // 判断当前的操作：新增 & 修改
              if (!this.formData.id) {
                // 新增
                var bool = res.depts.some(item => {
                  return item.code === value
                })
              } else {
                // 修改
                var bool = res.depts.some(item => {
                  return item.code === value && item.id !== this.currentObj.id
                })
              }
              !bool
                ? callback()
                : callback(new Error('当前 code 与其它部门冲突'))
            }
          }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'blur' }
        ],
        introduce: [
          { required: true, message: '部门描述不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 300,
            message: '部门描述长度在 1~300 之间',
            trigger: 'blur'
          }
        ]
      },
      // 负责人列表
      people: []
    }
  },
  computed: {
    mytitle () {
      // 判断是哪种操作（新增 & 修改）
      return !this.formData.id ? '新增部门' : '编辑部门'
    }
  },
  methods: {
    // 获取当前编辑的部门的信息
    //  这个方法在新增时是否需要调用？不需要
    //  这个方法在编辑时是否需要调用？需要
    async getDepartmentById (id) {
      this.formData = await getDepartmentByIdApi(id)
    },
    // 关闭面板 & 去掉校验判断
    cancel () {
      // 关闭面板
      this.$emit('update:showDialog', false)
      // 重置校验
      this.$refs.myform.resetFields()
    },
    // 提交新增的数据
    submit () {
      // 进行表单的全局验证
      this.$refs.myform.validate(async res => {
        if (res) {
          if (!this.formData.id) {
            // 新增
            // 全局验证通过：提交新增数据到服务器
            await addDepartmentApi({
              ...this.formData, // code & introduce & manager & name
              pid: this.currentObj.id
            })
          } else {
            // 修改
            await updateDeparmentApi(this.formData)
          }
          // 提示用户新增部门成功
          this.$message({
            type: 'success',
            message: '操作部门成功'
          })
          // 关闭面板：直接将 showDialog 设置为 false 就可以，
          // 但是由于这个属性是从父组件中传递过来的，如果直接修改会触发单向数据源，所以不能直接修改
          this.$emit('update:showDialog', false)
          // 自动更新数据源
          this.$emit('refreshdata')
          // 清空添加数据源
          this.formData = {
            name: '', // 部门名称
            code: '', // 部门编号
            manager: '', // 部门负责人
            introduce: '' // 部门介绍
          }
        }
      })
    },
    // 得到员工列表（负责人的列表）
    async getSimpleUser () {
      const res = await getSimpleUserAPi()
      this.people = res
    }
  },
  created () {
    this.getSimpleUser()
  }
}
</script>

<style lang="scss" scoped>
.add-depa {
}
</style>
